aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pages/og/[slug].png.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/pages/og/[slug].png.ts')
-rw-r--r--src/pages/og/[slug].png.ts52
1 files changed, 49 insertions, 3 deletions
diff --git a/src/pages/og/[slug].png.ts b/src/pages/og/[slug].png.ts
index 712a39f..67a4d7c 100644
--- a/src/pages/og/[slug].png.ts
+++ b/src/pages/og/[slug].png.ts
@@ -1,6 +1,9 @@
import satori from "satori";
import { Resvg } from "@resvg/resvg-js";
-import { readFileSync } from "node:fs";
+import { readFileSync, existsSync, readdirSync } from "node:fs";
+import path from "node:path";
+
+const contentDir = "src/content/docs";
const pages: Record<string, string> = {
index: "だれもがしあわせに暮らせるまちへ",
@@ -22,8 +25,45 @@ const pages: Record<string, string> = {
"ippan-situmon": "一般質問",
};
+function findMdxFiles(dir: string): string[] {
+ if (!existsSync(dir)) return [];
+ const files: string[] = [];
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
+ if (entry.name.startsWith(".") || entry.name.startsWith("_")) continue;
+ const full = path.join(dir, entry.name);
+ if (entry.isDirectory()) files.push(...findMdxFiles(full));
+ else if (entry.name.endsWith(".mdx")) files.push(full);
+ }
+ return files;
+}
+
+function readTitle(filePath: string): string | null {
+ try {
+ const content = readFileSync(filePath, "utf-8");
+ const m =
+ content.match(/^title:\s*"(.+?)"/m) ?? content.match(/^title:\s*(.+)/m);
+ return m?.[1] ?? null;
+ } catch {
+ return null;
+ }
+}
+
export async function getStaticPaths() {
- return Object.keys(pages).map((slug) => ({ params: { slug } }));
+ const slugs = new Set<string>();
+ // Manual pages
+ for (const s of Object.keys(pages)) slugs.add(s);
+ // Auto-discover ippan-situmon pages
+ for (const f of findMdxFiles(path.join(contentDir, "ippan-situmon"))) {
+ const s = f
+ .replace(/\\/g, "/")
+ .replace(contentDir + "/", "")
+ .replace(/\.mdx$/, "")
+ .replace(/\/index$/, "");
+ if (s) slugs.add(s);
+ }
+ return [...slugs]
+ .filter((s) => s.length > 0)
+ .map((slug) => ({ params: { slug: slug.replace(/\//g, "-") } }));
}
const fontBuffer = readFileSync("node_modules/.noto-sans-jp.otf");
@@ -72,7 +112,13 @@ const stars = [
export async function GET({ params }: { params: { slug: string } }) {
const slug = params.slug;
- const title = pages[slug] ?? "小平市議 安竹洋平 公式サイト";
+ // Convert - back to / for nested paths
+ const fileSlug = slug.replace(/-/g, "/");
+ let title = pages[fileSlug];
+ if (!title) {
+ const mdxPath = path.join(contentDir, fileSlug + ".mdx");
+ title = readTitle(mdxPath) ?? "小平市議 安竹洋平 公式サイト";
+ }
const svg = await satori(
{